﻿/***********************************************************************************************
 * 
 * ProjectName: WMSSoft.Lib.WinKStart
 * 
 * Description: Contains the Meta - Data about a Assembly
 * 
 * Created:     10.01.2015
 * 
 * Author:      matthias wagler - matthias@WMSSoft.de
 * 
 * Copyright:   Copyright 2015 by WMSSoft.net
 * 
 * License:     GPLv3
 * 
 * History:     10.01.2015 - matthias wagler matthias@WMSSoft.de   -   Created
 * 
 **********************************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WMSSoft.Lib.Basic;
using WMSSoft.Lib.Basic.Xml;
using WMSSoft.Lib.Const;
using WMSSoft.Lib.Enums;
using WMSSoft.Lib.Interfaces;
using WMSSoft.Lib.Texte;
using WMSSoft.Lib.WinKStart.Model.Metadata;
using System.Runtime.InteropServices;

namespace WMSSoft.Lib.WinKStart.Classes.Metadata
{
    public static class CMetaDataReader
    {
        public static Dictionary<string,CMeta> ReadAssemblies(string Path)
        {
            try
            {
                if (System.IO.Directory.Exists(Path) == true)
                {
                    Dictionary<string, CMeta> TmpREturn = new Dictionary<string, CMeta>();

                    string[] oFiles = System.IO.Directory.GetFiles(Path, "*.dll");
                    if (oFiles != null && oFiles.Count() > 0)
                    {
                        for (int iFileCounter = 0; iFileCounter < oFiles.Count(); iFileCounter++)
                        {
                            CMeta oTmpMetaData = ReadMetaData(oFiles[iFileCounter]);

                            if (oTmpMetaData != null)
                                TmpREturn.Add(oTmpMetaData.AssemblyName, oTmpMetaData);
                        }
                    }
                    return TmpREturn;
                }
                else return null;
            }
            catch (Exception Ex)
            {
                throw new Exception("Unable to read assemblies from  given Directory!");
            }
        }

        public static CMeta ReadMetaData(string AssemblyName)
        {
            try
            {
                string sPathToAssembly = "";
                //A Assembly can located in one of three Directories: DataSources, Functions, SearchEngines
                if (System.IO.File.Exists(System.IO.Path.Combine(WMSSoft.Lib.WinKStart.cUserSettingsReader.DataSourcesPath, AssemblyName)) == true)
                {
                    sPathToAssembly = WMSSoft.Lib.WinKStart.cUserSettingsReader.DataSourcesPath;
                }
                else if (System.IO.File.Exists(System.IO.Path.Combine(WMSSoft.Lib.WinKStart.cUserSettingsReader.FunctionsPaths, AssemblyName)) == true)
                {
                    sPathToAssembly = WMSSoft.Lib.WinKStart.cUserSettingsReader.FunctionsPaths;
                }
                else if (System.IO.File.Exists(System.IO.Path.Combine(WMSSoft.Lib.WinKStart.cUserSettingsReader.SearchEnginesPath, AssemblyName)) == true)
                {
                    sPathToAssembly = WMSSoft.Lib.WinKStart.cUserSettingsReader.SearchEnginesPath;
                }
                else
                {
                    throw new Exception(ErrorMessages.METADATA_READER__ERROR_ASSEMBLY_CANT_FOUND);
                }
                //Load Informations about the DataSource - Module using reflection                
                CMeta oAssemblyMeta = new CMeta();
                oAssemblyMeta.AssemblyName = System.IO.Path.GetFileName(AssemblyName);

                System.Reflection.Assembly oMetaAssembly = System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(sPathToAssembly, AssemblyName));
                Type[] oExpTypes = oMetaAssembly.GetExportedTypes();                

                foreach (Type ExpTypeItem in oExpTypes)
                {
                    Type[] oImplInterfaces = ExpTypeItem.GetInterfaces();
                    foreach (Type oImplInterface in oImplInterfaces)
                    {
                        if (oImplInterface.FullName == typeof(iWinKStartDataSource).FullName)
                        {
                            CMetaClass oMetaClass = new CMetaClass();
                            oMetaClass.Name = ExpTypeItem.FullName;
                            oAssemblyMeta.Classes.Add(oMetaClass);
                            //Close loop
                            break;
                        }
                    }

                }
                //Read Assembly Element Options
                oAssemblyMeta.ElementOptions = (ISourceElementOptions)oMetaAssembly.CreateInstance("WMSSoft.WinKStart.DataSource.RegisterDataSourcesOptions");

                return oAssemblyMeta;

            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage(ErrorMessages.METADATA_READER__ERROR_UNABLE_TO_READ_META_INFORMATION, Ex, EMessageTypes.Error);
                return null;
            }
        }

    }
}
